package net.app.zoneland.security.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**

 * @Description 身份认证拦截器
 * @Author cjb
 * @CreateTime 2020/12/27 16:33
 * @Version: 1.0
 */
@Configuration
//注解权限拦截
//@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true, jsr250Enabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Qualifier("userDetailsServiceImpl")
    @Autowired
    private UserDetailsService userDetailsService;

    /**
     * 认证服务器需要配置Security使用
     * @return
     * @throws Exception
     */
    @Bean
    @Override
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //验证用户权限
       auth.userDetailsService(userDetailsService);
    }


    //uri权限拦截,生产可以设置为启动动态读取数据库,具体百度
    @Override
    protected void configure(HttpSecurity http) throws Exception {
            http
                //此处不要禁止formLogin,code模式测试需要开启表单登陆,并且/oauth/token不要放开或放入下面ignoring,因为获取token首先需要登陆状态
              ///  .formLogin().loginPage("/authentication/require")
              //  .loginProcessingUrl("/authentication/form")
               // .passwordParameter("password")
               // .usernameParameter("username")
               // .and()
                    .logout().logoutUrl("/logout").logoutSuccessUrl("/")
                    // 配置允许访问的链接
                    .and().authorizeRequests().antMatchers("/oauth/**", "/login/**", "/oauth/logout","/rsa/publicKey").permitAll()
                    // 其余所有请求全部需要鉴权认证
                    .anyRequest().authenticated()
                    // 关闭跨域保护;
                    .and().csrf().disable();

             //   .csrf().disable()
             //   .authorizeRequests().antMatchers("/rsa/publicKey","/authentication/require","/oauth/logout").permitAll()
             //   .and()
             //   .authorizeRequests().anyRequest().authenticated();
    }

    //设置不拦截资源服务器的认证请求
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers("/oauth/check_token","/rsa/publicKey","/oauth/logout");
    }

    public static void main(String[] args) {
        String admin = new BCryptPasswordEncoder().encode("admin");
        System.out.println(admin);
    }
}
